#include <stdlib.h>

typedef struct List { 
	int v;
	struct List *next;
} list;

int is_null(list* node) {
	return node == NULL;
}

list* new_list(int v) {
	list* item = (list*)malloc(sizeof(list));
	item->v = v;
	item->next = NULL;
	return item;
}

void push_val(list* head, int v) {
	list* last = head;
	while(last->next != NULL) {
		last = last->next;
	}
	last->next = new_list(v);
}

void push_arr(list* ls, int* arr, int arr_len) {
	int i = 0;
	list* node = ls;
	for(; i < arr_len - 1; i++) {
		node->v = arr[i];
		node->next = new_list(0);
		node = node->next;
	} 
	node->v = arr[arr_len-1];
}


list* get_last(list* head) {
	list* last = head;
	while(last->next != NULL) {
		last = last->next;
	}
	return last;
}

int* get_last3v(list* head) {
	int arr[] = {0, 0, 0};
	list* last = head;
	while(last->next != NULL) {
		last = last->next;
		arr[2] = arr[1];
		arr[1] = arr[0];
		arr[0] = last->v;
	}
	return arr;
}

int count_list(list* head) {
	int count  = 0;
	list* last = head;
	while(last->next != NULL) {
		last = last->next;
		count ++;
	}
	return count;
}



// insert value into the list
// if the length > LEN, shift and push
void insert_val(list* head, int v, int len) {
	list* node = head;
	int c = count_list(head);
	if(c >= len) {
		while(node->next != NULL){
			node->v = node->next->v;
			node = node->next;
		}
		node->v = v;
	} else {
		push_val(head, v);
	}
}

void reset_list(list* head) {
	
	list* node = head->next; 
	
	while(node->next != NULL) {
		node->v = 0;
		node = node->next;
	}
	
	head->v = 0;
	head->next = NULL;
}

int get_max(list* head) {
	int max = 0;
	list* last = head;
	while(last->next != NULL) {
		max = max < last->v ? last->v : max;
		last = last->next;
		
	}
	return max;
}

int scale(int value) {
	
	int width = 400;
	int v = value > 0 ? value : -1 * value;
	
	if(v < width/16) {
		return -4;
	} else if(v < width/8) {
		return -3;
	} else if(v < width/4) {
		return -2;
	} else if(v < width/2) {
		return -1;
	} else if(v < width) {
		return 0;
	} else if(v < width*2) {
		return 1;
	} else {
		int s = 0;
		int i = 1;
		while(value/i > width) {
			i = i*2;
			s++;
		}
		return s;
	}
}

int draw_by_scale(int value, int scale) {
	if(scale == -4) {
		return value*16;
	} else if(scale == -3) {
		return value*8;
	}  else if(scale == -2) {
		return value*4;
	} else if(scale == -1) {
		return value*2;
	} else if(scale == 0) {
		return value;
	} else if(scale == 1) {
		return value/2;
	} else {
		int v = value;
		int i = scale;
		while(i--) {
			v = v/2;
		}
		return v;
	}
}

int compare_scale(list* head, int next) {
	int max = get_max(head);
	int v = max > next ? max : next;
	return scale(v);
}


int calc_list_scale(list* head) {
	int max = get_max(head); 
	return scale(max);
}

